using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using ODT.EtherCat.Core;

namespace PPPlotControl
{
	internal sealed class EtherCatNodeUpdater
	{
		private readonly IEtherCatVariableService etherCatVariableService;

		private readonly ISet<TreeNode> managedNodes = new HashSet<TreeNode>();

		private TreeNode etherCatNode;

		private TreeView treeView;

		private ListBox samples;

		private ListBox processData;

		private ListBox leftAxis;

		private ListBox rightAxis;

		public EtherCatNodeUpdater(IEtherCatVariableService etherCatVariableService)
		{
			this.etherCatVariableService = etherCatVariableService;
			this.etherCatVariableService.VariablesChanged += OnEtherCatVariableServiceChanged;
		}

		public void Update(TreeNode node, ListBox sampleListBox, ListBox processListBox, ListBox leftAxisListBox, ListBox rightAxisListBox)
		{
			etherCatNode = node;
			treeView = node.TreeView;
			samples = sampleListBox;
			processData = processListBox;
			leftAxis = leftAxisListBox;
			rightAxis = rightAxisListBox;
			Refresh();
		}

		public void Update()
		{
			if (etherCatNode != null)
			{
				Refresh();
			}
		}

		public void Remove()
		{
			etherCatVariableService.VariablesChanged -= OnEtherCatVariableServiceChanged;
		}

		private void Refresh()
		{
			treeView.CollapseAll();
			treeView.BeginUpdate();
			List<string> first = managedNodes.Select((TreeNode x) => x.Text).ToList();
			List<string> list = (from x in managedNodes
				where x.Checked
				select x.Text).ToList();
			foreach (TreeNode managedNode in managedNodes)
			{
				managedNode.Remove();
			}
			managedNodes.Clear();
			IReadOnlyCollection<IEtherCatVariable> variables = etherCatVariableService.Variables;
			foreach (IEtherCatVariable item in variables)
			{
				TreeNode treeNode = new TreeNode(item.Name)
				{
					Tag = true,
					Name = item.Name,
					ToolTipText = item.Address,
					Checked = list.Contains(item.Name)
				};
				etherCatNode.Nodes.Add(treeNode);
				managedNodes.Add(treeNode);
			}
			treeView.EndUpdate();
			treeView.Refresh();
			List<string> textsToDelete = first.Except(variables.Select((IEtherCatVariable x) => x.Name)).ToList();
			DeleteEtherCatVariableInListBox(samples, textsToDelete);
			DeleteEtherCatVariableInListBox(processData, textsToDelete);
			DeleteEtherCatVariableInListBox(leftAxis, textsToDelete);
			DeleteEtherCatVariableInListBox(rightAxis, textsToDelete);
		}

		private void DeleteEtherCatVariableInListBox(ListBox listBox, List<string> textsToDelete)
		{
			for (int num = listBox.Items.Count - 1; num >= 0; num--)
			{
				string item = listBox.Items[num].ToString();
				if (textsToDelete.Contains(item))
				{
					listBox.Items.RemoveAt(num);
				}
			}
			listBox.Refresh();
		}

		private void OnEtherCatVariableServiceChanged(object sender, EventArgs e)
		{
			treeView?.Invoke(new Action(Refresh));
		}
	}
}
